
package fr.ece.ing4.si.monteCarlo.thread;


import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;


public class MonteCarloMultiThread {

    int chargerSetNumber = 0;

    String valueSelection = "";
    double optionResult;
    long setTime, val1, val2;


    int poolSize = (int) (Runtime.getRuntime().availableProcessors() / (1 - 0.9));

    
  
    // Function
    public double monteCarloStandardOption2(String callPutFlag, final double s, double x, double t, double r, double b, double v, final double nSteps, double nSimulations) throws InterruptedException, ExecutionException {
        final double dt, drift, vsqrdt;
        double sum = 0.0;
        int i, z;

        final List<Callable<Double>> multiThread = new ArrayList<Callable<Double>>();

        dt = t / nSteps;
        drift = (b - Math.pow(v, 2) / 2) * dt;
        vsqrdt = v * Math.sqrt(dt);
        if (callPutFlag.equals("call"))
            z = 1;
        else
            z = -1;
        for (i = 0; i < nSimulations; i++) {
            //st=s
            multiThread.add(new Callable<Double>() {
                public Double call() {
                    final java.util.Random random = new java.util.Random();
                    double m = s;
                    int j;
                    for (j = 0; j < nSteps; j++) {
                        m = m * Math.exp(drift + vsqrdt * random.nextGaussian());
                    }
                    //System.out.println("yess "+m);
                    return m;
                    
                }
            });
            System.out.println("Output pool:" +poolSize);
        }
        final ExecutorService executorPool = Executors.newFixedThreadPool(4);
        //private Collection<? extends Callable<Double>> multiThread;
        final List<Future<Double>> set = executorPool.invokeAll(multiThread, 10000, TimeUnit.SECONDS);
        executorPool.shutdown();
        
        for (final Future<Double> resultMonteCarlo : set)
            sum += Math.max(z * (resultMonteCarlo.get() - x), 0);
        System.out.println("result multi " +Math.exp(-r * t) * (sum / nSimulations));
        return Math.exp(-r * t) * (sum / nSimulations);
       
    }

}		